﻿/**
 * @file		ct_dd_pmc_spi.c
 * @brief		PMC SPI driver Component Test
 * @note		None
 * @attention	None
 * 
 * <B><I>Copyright 2016 Socionext Inc.</I></B>
 */

#include "stdlib.h"
#include "string.h"
#include "pmc.h"
#include "dd_pmc_spi.h"
#include "ct_dd_pmc_spi.h"

/*----------------------------------------------------------------------*/
/* Definition															*/
/*----------------------------------------------------------------------*/
#define D_CT_DD_PMC_SPI_DMA_CH_1				(6)
#define D_CT_DD_PMC_SPI_DMA_CH_2				(7)

/*----------------------------------------------------------------------*/
/* Enumeration															*/
/*----------------------------------------------------------------------*/
typedef enum {
	E_CT_DD_PMC_SPI_TRNAS_TYPE_SEND = 0,
	E_CT_DD_PMC_SPI_TRNAS_TYPE_RECV,
	E_CT_DD_PMC_SPI_TRNAS_TYPE_FULL,
	E_CT_DD_PMC_SPI_TRNAS_TYPE_GYRO
} E_CT_DD_PMC_SPI_TRNAS_TYPE;

/*----------------------------------------------------------------------*/
/* Global Data															*/
/*----------------------------------------------------------------------*/
static UCHAR  gCT_DD_PMC_SPI_Send_Buf8[32] = {0};
static USHORT gCT_DD_PMC_SPI_Send_Buf16[32] = {0};
static UCHAR  gCT_DD_PMC_SPI_Recv_Buf8[32] = {0};
static USHORT gCT_DD_PMC_SPI_Recv_Buf16[32] = {0};

static E_CT_DD_PMC_SPI_TRNAS_TYPE gCT_DD_PMC_SPI_Trans_Type = E_CT_DD_PMC_SPI_TRNAS_TYPE_SEND;
static UINT32 gCT_DD_PMC_SPI_Trans_Num;
static E_DD_PMC_SPI_BIT_LEN gCT_DD_PMC_SPI_Bit_Len;

static UCHAR gCT_DD_PMC_SPI_Async;
static ULONG gCT_DD_PMC_SPI_Send_Data_Addr;
static ULONG gCT_DD_PMC_SPI_Recv_Data_Addr;

static UCHAR gCT_DD_PMC_SPI_PC_DMA_Async = 0;

/*----------------------------------------------------------------------*/
/* Local Function														*/
/*----------------------------------------------------------------------*/
static VOID ct_dd_pmc_spi_print_send_data( VOID )
{
	INT32 index;

	if( !gCT_DD_PMC_SPI_Send_Data_Addr ){
		Ddim_Print(("---Send data---\n"));
		if( gCT_DD_PMC_SPI_Bit_Len > E_DD_PMC_SPI_BIT_LEN_8 ){
			for( index = 0; index < gCT_DD_PMC_SPI_Trans_Num; index++ ){
				Ddim_Print(("gCT_DD_PMC_SPI_Send_Buf16[%d] = 0x%04X\n", index, gCT_DD_PMC_SPI_Send_Buf16[index]));
			}
		}
		else {
			for( index = 0; index < gCT_DD_PMC_SPI_Trans_Num; index++ ){
				Ddim_Print(("gCT_DD_PMC_SPI_Send_Buf8[%d] = 0x%02X\n", index, gCT_DD_PMC_SPI_Send_Buf8[index]));
			}
		}
	}
}

static VOID ct_dd_pmc_spi_print_recv_data( VOID )
{
	INT32 index;

	if( !gCT_DD_PMC_SPI_Recv_Data_Addr ){
		Ddim_Print(("---Receive data---\n"));
		if( gCT_DD_PMC_SPI_Bit_Len > E_DD_PMC_SPI_BIT_LEN_8 ){
			for( index = 0; index < gCT_DD_PMC_SPI_Trans_Num; index++ ){
				Ddim_Print(("gCT_DD_PMC_SPI_Recv_Buf16[%d] = 0x%04X\n", index, gCT_DD_PMC_SPI_Recv_Buf16[index]));
			}
		}
		else {
			for( index = 0; index < gCT_DD_PMC_SPI_Trans_Num; index++ ){
				Ddim_Print(("gCT_DD_PMC_SPI_Recv_Buf8[%d] = 0x%02X\n", index, gCT_DD_PMC_SPI_Recv_Buf8[index]));
			}
		}
	}
}

static VOID ct_dd_pmc_spi_print_data( VOID )
{
	if( gCT_DD_PMC_SPI_Trans_Type == E_CT_DD_PMC_SPI_TRNAS_TYPE_SEND ){
		ct_dd_pmc_spi_print_send_data();
	}
	else if( gCT_DD_PMC_SPI_Trans_Type == E_CT_DD_PMC_SPI_TRNAS_TYPE_RECV ){
		ct_dd_pmc_spi_print_recv_data();
	}
	else {	// E_CT_DD_PMC_SPI_TRNAS_TYPE_FULL
		ct_dd_pmc_spi_print_send_data();
		ct_dd_pmc_spi_print_recv_data();
	}
}

static VOID ct_dd_pmc_spi_print_ctrl( T_DD_PMC_SPI_CTRL const* const spi_ctrl )
{
	Ddim_Print(("SPI type               =%d\n", spi_ctrl->type));
	Ddim_Print(("SPI mode               =%d\n", spi_ctrl->mode));
	Ddim_Print(("SPI enable_sig         =%d\n", spi_ctrl->enable_sig));
	Ddim_Print(("SPI bit_direction      =%d\n", spi_ctrl->bit_direction));
	Ddim_Print(("SPI bit_length         =%d\n", spi_ctrl->bit_length));
	Ddim_Print(("SPI clk_div            =%d\n", spi_ctrl->clk_div));
	Ddim_Print(("SPI delay_en           =%d\n", spi_ctrl->delay_en));
	Ddim_Print(("SPI delay_val          =%d\n", spi_ctrl->delay_val));
	Ddim_Print(("SPI rx_inhibit_en      =%d\n", spi_ctrl->rx_inhibit_en));
	Ddim_Print(("SPI fifo_depth         =%d\n", spi_ctrl->fifo_depth));
	Ddim_Print(("SPI fifo_wmark_tx      =%d\n", spi_ctrl->fifo_wmark_tx));
	Ddim_Print(("SPI fifo_wmark_rx      =%d\n", spi_ctrl->fifo_wmark_rx));
	Ddim_Print(("SPI dma_en             =%d\n", spi_ctrl->dma_en));
	Ddim_Print(("SPI dma_recv_to        =%d\n", spi_ctrl->dma_recv_to));
	Ddim_Print(("SPI ss_info.cont_trans =%d\n", spi_ctrl->ss_info.cont_trans));
	Ddim_Print(("SPI ss_info.ssout      =%d\n", spi_ctrl->ss_info.ssout));
	Ddim_Print(("SPI ss_info.sspol      =%d\n", spi_ctrl->ss_info.sspol));
	Ddim_Print(("SPI pcallback_ss       =0x%x\n", spi_ctrl->pcallback_ss));
}

static VOID ct_dd_pmc_spi_print_dma_reg( UCHAR dma_ch )
{
	Ddim_Print(("EN.bit.__ENABLEREQ      = %d\n", IO_PMC.SPI.EN.bit.__ENABLEREQ));
	Ddim_Print(("INT_EN.word             = 0x%08X\n", IO_PMC.SPI.INT_EN.word));
/*
	Ddim_Print(("DMACA.bit.EB            = %d\n", IO_HDMAC1.DMAC[dma_ch].DMACA.bit.EB));
	Ddim_Print(("DMACA.bit.IS            = 0x%02X\n", IO_HDMAC1.DMAC[dma_ch].DMACA.bit.IS));
	Ddim_Print(("DMACB.bit.TW            = %d\n", IO_HDMAC1.DMAC[dma_ch].DMACB.bit.TW));
	Ddim_Print(("DMACA.bit.TC            = %d\n", IO_HDMAC1.DMAC[dma_ch].DMACA.bit.TC));
	Ddim_Print(("DMACB.bit.FD            = %d\n", IO_HDMAC1.DMAC[dma_ch].DMACB.bit.FD));
	Ddim_Print(("DMACB.bit.FS            = %d\n", IO_HDMAC1.DMAC[dma_ch].DMACB.bit.FS));
	Ddim_Print(("DMACB.bit.RC            = %d\n", IO_HDMAC1.DMAC[dma_ch].DMACB.bit.RC));
*/
}

static VOID ct_dd_pmc_spi_print_dma_full_reg( UCHAR send_dma_ch, UCHAR recv_dma_ch )
{
	Ddim_Print(("EN.bit.__ENABLEREQ      = %d\n", IO_PMC.SPI.EN.bit.__ENABLEREQ));
	Ddim_Print(("INT_EN.word             = 0x%08X\n", IO_PMC.SPI.INT_EN.word));
/*
	Ddim_Print(("DMACA.bit.EB(send)      = %d\n", IO_HDMAC1.DMAC[send_dma_ch].DMACA.bit.EB));
	Ddim_Print(("DMACA.bit.IS(send)      = 0x%02X\n", IO_HDMAC1.DMAC[send_dma_ch].DMACA.bit.IS));
	Ddim_Print(("DMACA.bit.TC(send)      = %d\n", IO_HDMAC1.DMAC[send_dma_ch].DMACA.bit.TC));
	Ddim_Print(("DMACB.bit.RC(send)      = %d\n", IO_HDMAC1.DMAC[send_dma_ch].DMACB.bit.RC));
	Ddim_Print(("DMACA.bit.EB(recv)      = %d\n", IO_HDMAC1.DMAC[recv_dma_ch].DMACA.bit.EB));
	Ddim_Print(("DMACA.bit.IS(send)      = 0x%02X\n", IO_HDMAC1.DMAC[recv_dma_ch].DMACA.bit.IS));
	Ddim_Print(("DMACA.bit.TC(recv)      = %d\n", IO_HDMAC1.DMAC[recv_dma_ch].DMACA.bit.TC));
	Ddim_Print(("DMACB.bit.RC(recv)      = %d\n", IO_HDMAC1.DMAC[recv_dma_ch].DMACB.bit.RC));
*/
}

static VOID ct_dd_pmc_spi_send_callback( UINT32 result )
{
	Ddim_Print(("SPI Send Callback. result=0x%08X\n", result));

	if( gCT_DD_PMC_SPI_PC_DMA_Async ){
		if( gCT_DD_PMC_SPI_Trans_Type == E_CT_DD_PMC_SPI_TRNAS_TYPE_FULL ){
			ct_dd_pmc_spi_print_dma_full_reg( D_CT_DD_PMC_SPI_DMA_CH_1, D_CT_DD_PMC_SPI_DMA_CH_2 );
		}
		else {
			ct_dd_pmc_spi_print_dma_reg( D_CT_DD_PMC_SPI_DMA_CH_1 );
		}
	}

	if( result == D_DDIM_OK ){
		if( !gCT_DD_PMC_SPI_Async ){
			ct_dd_pmc_spi_print_data();
		}
	}
}
static VOID ct_dd_pmc_spi_receive_callback( UINT32 result )
{
	Ddim_Print(("SPI Receive Callback. result=0x%08X\n", result));

	if( gCT_DD_PMC_SPI_PC_DMA_Async ){
		if( gCT_DD_PMC_SPI_Trans_Type == E_CT_DD_PMC_SPI_TRNAS_TYPE_FULL ){
			ct_dd_pmc_spi_print_dma_full_reg( D_CT_DD_PMC_SPI_DMA_CH_1, D_CT_DD_PMC_SPI_DMA_CH_2 );
		}
		else {
			ct_dd_pmc_spi_print_dma_reg( D_CT_DD_PMC_SPI_DMA_CH_1 );
		}
	}

	if( result == D_DDIM_OK ){
		if( !gCT_DD_PMC_SPI_Async ){
			ct_dd_pmc_spi_print_data();
		}
	}
}

static VOID ct_dd_pmc_spi_callback_ss( VOID )
{
	Ddim_Print(("SPI Callback of SSOUT/IN\n"));
}


/**
 * @brief  Command main function for SPI test.
 * @param  INT32 argc	:The number of parameters
 *		   CGAR** argv	:The value of parameters
 * @return VOID
 */
VOID Ct_Dd_Pmc_SPI_Main( int argc, char** argv )
{
	INT32					ret = D_DDIM_OK;
	INT32					pattern = 0;
	UINT32					val;
	UCHAR					clk_div = 0;
	CHAR*					endstr;
	ULONG					baudrate;
	T_DD_PMC_SPI_CTRL		spi_ctrl;
	T_DD_PMC_SPI_SS_INFO	ss_info;

	if( strcmp(argv[1], "cal") == 0 ){			// Calc
		baudrate = atoi( argv[2] );

		ret = Dd_PMC_SPI_Calculate( baudrate, &clk_div );

		Ddim_Print(("Dd_PMC_SPI_Calculate() End. ret=0x%08X, clk_div=%d\n", ret, clk_div));
	}
	else if( strcmp(argv[1], "ctrl") == 0 ){		// Set Control
		//
		// spi ctrl 0 [type] [mode] [sig] [msb] [bit] [bps] [dly] [inhrx] [txwmk] [rxwmk]
		// spi ctrl 1 [dma/cpu] [timeout] [ssout] [sspol] [cont_trans] [cbss]
		// spi ctrl 2
		//
		
		pattern = atoi( argv[2] );
		if (pattern == 0) {
			// Get Control information.
			Dd_PMC_SPI_Get_Ctrl( &spi_ctrl );
			
			// Type
			if( strcmp(argv[3], "ms") == 0 ){
				spi_ctrl.type = E_DD_PMC_SPI_TYPE_MASTER;
			}
			else if( strcmp(argv[3], "sl") == 0 ){
				spi_ctrl.type = E_DD_PMC_SPI_TYPE_SLAVE;
			}
			else{
				Ddim_Print( ("please check type parameter!!\n" ) );
				return;
			}

			// Mode
			spi_ctrl.mode = atoi( argv[4] );
			if( spi_ctrl.mode > E_DD_PMC_SPI_MODE_3_CPOL1_CPHA1 ){
				Ddim_Print( ("please check mode parameter!!\n" ) );
				return;
			}

			// Enable signal
			spi_ctrl.enable_sig = atoi( argv[5] );
			if( spi_ctrl.enable_sig > E_DD_PMC_SPI_ENABLE_SIG_EXT_2 ){
				Ddim_Print( ("please check enable_sig parameter!!\n" ) );
				return;
			}

			// LSB first or MSB first
			if( strcmp(argv[6], "lsb") == 0 ){
				spi_ctrl.bit_direction = E_DD_PMC_SPI_BIT_DIR_LSB_FIRST;
			}
			else if( strcmp(argv[6], "msb") == 0 ){
				spi_ctrl.bit_direction = E_DD_PMC_SPI_BIT_DIR_MSB_FIRST;
			}
			else{
				Ddim_Print( ("please check bit_direction parameter!!\n" ) );
				return;
			}

			// Bit length
			spi_ctrl.bit_length = atoi( argv[7] ) - 1;
			if( ( spi_ctrl.bit_length < E_DD_PMC_SPI_BIT_LEN_4 ) ||
				( spi_ctrl.bit_length > E_DD_PMC_SPI_BIT_LEN_16 ) ){
				Ddim_Print( ("please check bit_length parameter!!\n" ) );
				return;
			}
			gCT_DD_PMC_SPI_Bit_Len = spi_ctrl.bit_length;

			// Baudrate (bps)
			baudrate = atol(argv[8]);
			ret = Dd_PMC_SPI_Calculate( baudrate, &clk_div );
			if( ret !=D_DDIM_OK ){
				Ddim_Print(("SPI Calc ERR. ret=0x%08X\n", ret));
				return;
			}
			spi_ctrl.clk_div = clk_div;

			// Inter-Transfer Delay
			val = atoi( argv[9] );
			if( val == 0 ){
				spi_ctrl.delay_val = 0;
				spi_ctrl.delay_en = 0;
			}
			else if( val < 256 ){
				spi_ctrl.delay_val = val;
				spi_ctrl.delay_en = 1;
			}
			else {
				Ddim_Print( ("please check delay parameter!!\n" ) );
				return;
			}

			// Inhibit the RX_FIFO
			val = atoi( argv[10] );
			if( val == 0 ){
				spi_ctrl.rx_inhibit_en = 0;
			}
			else if( val == 1 ){
				spi_ctrl.rx_inhibit_en = 1;
			}
			else {
				Ddim_Print( ("please check rx_inhibit_en parameter!!\n" ) );
				return;
			}

			// TX FIFO Watermark
			spi_ctrl.fifo_wmark_tx = atoi( argv[11] );
			if( spi_ctrl.fifo_wmark_tx > spi_ctrl.fifo_depth ){
				Ddim_Print( ("please check fifo_wmark_tx parameter!!\n" ) );
				return;
			}

			// RX FIFO Watermark
			spi_ctrl.fifo_wmark_rx = atoi( argv[12] );
			if( spi_ctrl.fifo_wmark_rx > spi_ctrl.fifo_depth ){
				Ddim_Print( ("please check fifo_wmark_rx parameter!!\n" ) );
				return;
			}
			
			// Set Control information.
			ret = Dd_PMC_SPI_Ctrl( &spi_ctrl );
			Ddim_Print(("Dd_PMC_SPI_Ctrl() End. ret=0x%08X\n", ret));
		}
		else if (pattern == 1) {
			// Get Control information.
			Dd_PMC_SPI_Get_Ctrl( &spi_ctrl );
			
			spi_ctrl.fifo_depth = 16;

			// DMA enable
			if( strcmp(argv[3], "dma") == 0 ){
				spi_ctrl.dma_en = 1;

				val = atoi( argv[4] );
				if( val > 0xFFFFFF ){
					spi_ctrl.dma_recv_to = val;
				}
				else {
					Ddim_Print( ("please check dma_recv_to parameter!!\n" ) );
					return;
				}
			}
			else if( strcmp(argv[3], "cpu") == 0 ){
				spi_ctrl.dma_en = 0;
				spi_ctrl.dma_recv_to = 0;
			}
			else{
				Ddim_Print( ("please check dma_en parameter!!\n" ) );
				return;
			}

			// Slave Select Output
			val = atoi( argv[5] );
			if( val == 1 ){
				spi_ctrl.ss_info.ssout = 1;
			}
			else {
				spi_ctrl.ss_info.ssout = 0;
			}

			// Slave Select Polarity
			val = atoi( argv[6] );
			if( val == 1 ){
				spi_ctrl.ss_info.sspol = 1;
			}
			else {
				spi_ctrl.ss_info.sspol = 0;
			}

			// ssOUT Continuous Transfer
			spi_ctrl.ss_info.cont_trans = atoi( argv[7] );
			if( spi_ctrl.ss_info.cont_trans > E_DD_PMC_SPI_CONT_TRANS_ACT_FIFO_EMPTY ){
				Ddim_Print( ("please check cont_trans parameter!!\n" ) );
				return;
			}

			// Callback function for ssIN/OUT
			val = atoi( argv[8] );
			if( val == 0 ){
				spi_ctrl.pcallback_ss = NULL;
			}
			else{
				spi_ctrl.pcallback_ss = ct_dd_pmc_spi_callback_ss;
				gCT_DD_PMC_SPI_Async = 1;
			}

			// Set Control
			ret = Dd_PMC_SPI_Ctrl( &spi_ctrl );

			Ddim_Print(("Dd_PMC_SPI_Ctrl() End. ret=0x%08X\n", ret));
		}
		else if (pattern == 2) {
			spi_ctrl.type				= E_DD_PMC_SPI_TYPE_MASTER;
			spi_ctrl.mode				= E_DD_PMC_SPI_MODE_3_CPOL1_CPHA1;
			spi_ctrl.enable_sig			= E_DD_PMC_SPI_ENABLE_SIG_CPU;
			spi_ctrl.bit_direction		= E_DD_PMC_SPI_BIT_DIR_MSB_FIRST;
			spi_ctrl.bit_length			= E_DD_PMC_SPI_BIT_LEN_8;
			spi_ctrl.clk_div			= 0;
			spi_ctrl.delay_en			= 0;
			spi_ctrl.delay_val			= 0;
			spi_ctrl.rx_inhibit_en		= 1;
			spi_ctrl.fifo_depth			= 16;
			spi_ctrl.fifo_wmark_tx		= 0;
			spi_ctrl.fifo_wmark_rx		= 8;
			spi_ctrl.dma_en				= 0;
			spi_ctrl.dma_recv_to		= 0;
			spi_ctrl.ss_info.cont_trans	= E_DD_PMC_SPI_CONT_TRANS_ACT_FIFO_EMPTY;
			spi_ctrl.ss_info.ssout		= 1;
			spi_ctrl.ss_info.sspol		= 0;
			spi_ctrl.pcallback_ss		= ct_dd_pmc_spi_callback_ss;
			
			gCT_DD_PMC_SPI_Bit_Len = spi_ctrl.bit_length;
			
			// Set Control
			ret = Dd_PMC_SPI_Ctrl( &spi_ctrl );

			Ddim_Print(("Dd_PMC_SPI_Ctrl() End. ret=0x%08X\n", ret));
		}
		else if (pattern == 3) {
			spi_ctrl.type				= E_DD_PMC_SPI_TYPE_MASTER;
			spi_ctrl.mode				= E_DD_PMC_SPI_MODE_3_CPOL1_CPHA1;
			spi_ctrl.enable_sig			= E_DD_PMC_SPI_ENABLE_SIG_CPU;
			spi_ctrl.bit_direction		= E_DD_PMC_SPI_BIT_DIR_MSB_FIRST;
			spi_ctrl.bit_length			= E_DD_PMC_SPI_BIT_LEN_8;
			spi_ctrl.clk_div			= 0;
			spi_ctrl.delay_en			= 0;
			spi_ctrl.delay_val			= 0;
			spi_ctrl.rx_inhibit_en		= 0;
			spi_ctrl.fifo_depth			= 16;
			spi_ctrl.fifo_wmark_tx		= 0;
			spi_ctrl.fifo_wmark_rx		= 8;
			spi_ctrl.dma_en				= 0;
			spi_ctrl.dma_recv_to		= 0;
			spi_ctrl.ss_info.cont_trans	= E_DD_PMC_SPI_CONT_TRANS_ACT_FIFO_EMPTY;
			spi_ctrl.ss_info.ssout		= 1;
			spi_ctrl.ss_info.sspol		= 0;
			spi_ctrl.pcallback_ss		= ct_dd_pmc_spi_callback_ss;
			
			gCT_DD_PMC_SPI_Bit_Len = spi_ctrl.bit_length;
			
			// Set Control
			ret = Dd_PMC_SPI_Ctrl( &spi_ctrl );

			Ddim_Print(("Dd_PMC_SPI_Ctrl() End. ret=0x%08X\n", ret));
		}
		else if (pattern == 4) {
			spi_ctrl.type				= E_DD_PMC_SPI_TYPE_SLAVE;
			spi_ctrl.mode				= E_DD_PMC_SPI_MODE_3_CPOL1_CPHA1;
			spi_ctrl.enable_sig			= E_DD_PMC_SPI_ENABLE_SIG_CPU;
			spi_ctrl.bit_direction		= E_DD_PMC_SPI_BIT_DIR_MSB_FIRST;
			spi_ctrl.bit_length			= E_DD_PMC_SPI_BIT_LEN_8;
			spi_ctrl.clk_div			= 0;
			spi_ctrl.delay_en			= 0;
			spi_ctrl.delay_val			= 0;
			spi_ctrl.rx_inhibit_en		= 1;
			spi_ctrl.fifo_depth			= 16;
			spi_ctrl.fifo_wmark_tx		= 0;
			spi_ctrl.fifo_wmark_rx		= 8;
			spi_ctrl.dma_en				= 0;
			spi_ctrl.dma_recv_to		= 0;
			spi_ctrl.ss_info.cont_trans	= E_DD_PMC_SPI_CONT_TRANS_ACT_FIFO_EMPTY;
			spi_ctrl.ss_info.ssout		= 1;
			spi_ctrl.ss_info.sspol		= 0;
			spi_ctrl.pcallback_ss		= ct_dd_pmc_spi_callback_ss;
			
			gCT_DD_PMC_SPI_Bit_Len = spi_ctrl.bit_length;
			
			// Set Control
			ret = Dd_PMC_SPI_Ctrl( &spi_ctrl );

			Ddim_Print(("Dd_PMC_SPI_Ctrl() End. ret=0x%08X\n", ret));
		}
		else if (pattern == 5) {
			spi_ctrl.type				= E_DD_PMC_SPI_TYPE_SLAVE;
			spi_ctrl.mode				= E_DD_PMC_SPI_MODE_3_CPOL1_CPHA1;
			spi_ctrl.enable_sig			= E_DD_PMC_SPI_ENABLE_SIG_CPU;
			spi_ctrl.bit_direction		= E_DD_PMC_SPI_BIT_DIR_MSB_FIRST;
			spi_ctrl.bit_length			= E_DD_PMC_SPI_BIT_LEN_8;
			spi_ctrl.clk_div			= 0;
			spi_ctrl.delay_en			= 0;
			spi_ctrl.delay_val			= 0;
			spi_ctrl.rx_inhibit_en		= 0;
			spi_ctrl.fifo_depth			= 16;
			spi_ctrl.fifo_wmark_tx		= 0;
			spi_ctrl.fifo_wmark_rx		= 8;
			spi_ctrl.dma_en				= 0;
			spi_ctrl.dma_recv_to		= 0;
			spi_ctrl.ss_info.cont_trans	= E_DD_PMC_SPI_CONT_TRANS_ACT_FIFO_EMPTY;
			spi_ctrl.ss_info.ssout		= 1;
			spi_ctrl.ss_info.sspol		= 0;
			spi_ctrl.pcallback_ss		= ct_dd_pmc_spi_callback_ss;
			
			gCT_DD_PMC_SPI_Bit_Len = spi_ctrl.bit_length;
			
			// Set Control
			ret = Dd_PMC_SPI_Ctrl( &spi_ctrl );

			Ddim_Print(("Dd_PMC_SPI_Ctrl() End. ret=0x%08X\n", ret));
		}
	}
	else if( strcmp(argv[1], "get_ctrl") == 0 ){
		memset(&spi_ctrl, 0, sizeof(T_DD_PMC_SPI_CTRL));
		
		ret = Dd_PMC_SPI_Get_Ctrl( &spi_ctrl );

		Ddim_Print(("Dd_PMC_SPI_Get_Ctrl() End. ret=0x%08X\n", ret));
		ct_dd_pmc_spi_print_ctrl( &spi_ctrl );
	}
	else if( strcmp(argv[1], "set_send") == 0 ){			// Set send data
		// spi set_send [num] [addr value] [data value]
		UCHAR	data;

		// Data size
		gCT_DD_PMC_SPI_Trans_Num = atoi(argv[2]);
		gCT_DD_PMC_SPI_Send_Data_Addr = strtoul( argv[3], &endstr, 16 );
		data = strtoul( argv[4], &endstr, 16 );

		if (gCT_DD_PMC_SPI_Send_Data_Addr == 0) {
			if( gCT_DD_PMC_SPI_Bit_Len > E_DD_PMC_SPI_BIT_LEN_8 ){
				memset( gCT_DD_PMC_SPI_Send_Buf16, data, sizeof(gCT_DD_PMC_SPI_Send_Buf16) );	/* pgr0539 */

				// Set send data
				ret = Dd_PMC_SPI_Set_Send_Data( gCT_DD_PMC_SPI_Send_Buf16, gCT_DD_PMC_SPI_Trans_Num );
			}
			else {
				memset( gCT_DD_PMC_SPI_Send_Buf8, data, sizeof(gCT_DD_PMC_SPI_Send_Buf8) );		/* pgr0539 */

				// Set send data
				ret = Dd_PMC_SPI_Set_Send_Data( gCT_DD_PMC_SPI_Send_Buf8, gCT_DD_PMC_SPI_Trans_Num );
			}
		}
		else {
			if( gCT_DD_PMC_SPI_Bit_Len > E_DD_PMC_SPI_BIT_LEN_8 ){
				memset( (VOID*)gCT_DD_PMC_SPI_Send_Data_Addr, data, (gCT_DD_PMC_SPI_Trans_Num * 2) );	/* pgr0539 */
			}
			else {
				memset( (VOID*)gCT_DD_PMC_SPI_Send_Data_Addr, data, gCT_DD_PMC_SPI_Trans_Num );		/* pgr0539 */
			}

			// Set send data
			ret = Dd_PMC_SPI_Set_Send_Data( (VOID*)gCT_DD_PMC_SPI_Send_Data_Addr, gCT_DD_PMC_SPI_Trans_Num );
		}
		
		Ddim_Print(("Dd_PMC_SPI_Set_Send_Data() End. ret=0x%08X\n", ret));
	}
	else if( strcmp(argv[1], "set_recv") == 0 ){			// Set revceive data
		// spi set_recv [num] [addr value]

		// Data size
		gCT_DD_PMC_SPI_Trans_Num = atoi(argv[2]);
		gCT_DD_PMC_SPI_Recv_Data_Addr = strtoul( argv[3], &endstr, 16 );
		
		if (gCT_DD_PMC_SPI_Recv_Data_Addr != 0) {
			if( gCT_DD_PMC_SPI_Bit_Len > E_DD_PMC_SPI_BIT_LEN_8 ){
				memset( (VOID*)gCT_DD_PMC_SPI_Recv_Data_Addr, 0, (gCT_DD_PMC_SPI_Trans_Num * 2) );	/* pgr0539 */
			}
			else {
				memset( (VOID*)gCT_DD_PMC_SPI_Recv_Data_Addr, 0, gCT_DD_PMC_SPI_Trans_Num );			/* pgr0539 */
			}

			// Set receive data
			ret = Dd_PMC_SPI_Set_Recv_Data( (VOID*)gCT_DD_PMC_SPI_Recv_Data_Addr, gCT_DD_PMC_SPI_Trans_Num );
		}
		else {
			if( gCT_DD_PMC_SPI_Bit_Len > E_DD_PMC_SPI_BIT_LEN_8 ){
				memset( gCT_DD_PMC_SPI_Recv_Buf16, 0, sizeof(gCT_DD_PMC_SPI_Recv_Buf16) );

				// Set receive data
				ret = Dd_PMC_SPI_Set_Recv_Data( gCT_DD_PMC_SPI_Recv_Buf16, gCT_DD_PMC_SPI_Trans_Num );
			}
			else {
				memset( gCT_DD_PMC_SPI_Recv_Buf8, 0, sizeof(gCT_DD_PMC_SPI_Recv_Buf8) );

				// Set receive data
				ret = Dd_PMC_SPI_Set_Recv_Data( gCT_DD_PMC_SPI_Recv_Buf8, gCT_DD_PMC_SPI_Trans_Num );
			}
		}
		
		Ddim_Print(("Dd_PMC_SPI_Set_Recv_Data() End. ret=0x%08X\n", ret));
	}
	else if ( strcmp( argv[1], "start_send" ) == 0 ){		// Start send
		gCT_DD_PMC_SPI_Trans_Type = E_CT_DD_PMC_SPI_TRNAS_TYPE_SEND;
		
		val = atoi( argv[2] );
		
		if (val == 1) {
			ret = Dd_PMC_SPI_Start_Send( NULL );
			if (ret == D_DDIM_OK) {
				ct_dd_pmc_spi_print_data();
			}
		}
		else {
			ret = Dd_PMC_SPI_Start_Send( ct_dd_pmc_spi_send_callback );
		}

		Ddim_Print(("Dd_PMC_SPI_Start_Send() End. ret=0x%08X\n", ret));
	}
	else if ( strcmp( argv[1], "start_recv" ) == 0 ){		// Start receive
		gCT_DD_PMC_SPI_Trans_Type = E_CT_DD_PMC_SPI_TRNAS_TYPE_RECV;
		
		val = atoi( argv[2] );
		
		if (val == 1) {
			ret = Dd_PMC_SPI_Start_Recv( NULL );
			if (ret == D_DDIM_OK) {
				ct_dd_pmc_spi_print_data();
			}
		}
		else {
			ret = Dd_PMC_SPI_Start_Recv( ct_dd_pmc_spi_receive_callback );
		}
		
		Ddim_Print(("Dd_PMC_SPI_Start_Recv() End. ret=0x%08X\n", ret));
	}
	else if ( strcmp( argv[1], "start_full" ) == 0 ){
		gCT_DD_PMC_SPI_Trans_Type = E_CT_DD_PMC_SPI_TRNAS_TYPE_FULL;

		ret = Dd_PMC_SPI_Start_Full_Duplex( ct_dd_pmc_spi_send_callback, ct_dd_pmc_spi_receive_callback );

		Ddim_Print(("Dd_PMC_SPI_Start_Full_Duplex() End. ret=0x%08X\n", ret));
	}
	else if ( strcmp( argv[1], "stop" ) == 0 ){
		Dd_PMC_SPI_Stop();

		Ddim_Print(("Dd_PMC_SPI_Stop() End.\n"));
	}
	else if ( strcmp( argv[1], "set_ss" ) == 0 ){
		// spi set_ss [cont_trans] [ssout] [sspol]
		ss_info.cont_trans = atoi( argv[2] );
		ss_info.ssout = atoi( argv[3] );
		ss_info.sspol = atoi( argv[4] );

		ret = Dd_PMC_SPI_Set_Slave_Select( &ss_info );

		Ddim_Print(("Dd_PMC_SPI_Set_Slave_Select End. ret=0x%08X\n", ret));
	}
	else if ( strcmp( argv[1], "get_ss" ) == 0 ){

		ret = Dd_PMC_SPI_Get_Slave_Select( &ss_info );

		Ddim_Print(("Dd_PMC_SPI_Get_Slave_Select End. ret=0x%08X\n", ret));

		Ddim_Print(("---SS_INFO---\n"));
		Ddim_Print(("cont_trans = %d\n", ss_info.cont_trans));
		Ddim_Print(("ssout      = %d\n", ss_info.ssout));
		Ddim_Print(("sspol      = %d\n", ss_info.sspol));
	}
	else if ( strcmp( argv[1], "set_div" ) == 0 ){
		clk_div = atoi( argv[2] );

		Dd_PMC_SPI_Set_Clock_Divisor( clk_div );

		Ddim_Print(("Dd_PMC_SPI_Set_Clock_Divisor End.\n"));
	}
	else if ( strcmp( argv[1], "get_div" ) == 0 ){
		ret = Dd_PMC_SPI_Get_Clock_Divisor( &clk_div );

		Ddim_Print(("Dd_PMC_SPI_Get_Clock_Divisor End. ret=0x%08X, clk_div=%d\n", ret, clk_div));
	}
	else if (strcmp(argv[1], "err") == 0){
		int num;
		num = atoi(argv[2]);
		switch( num ) {
		case 1:
			ret = Dd_PMC_SPI_Ctrl( NULL );
			Ddim_Print(("Dd_PMC_SPI_Ctrl(): spi_ctrl is NULL. ret=%X\n", ret ));
			break;
		case 2:
			ret = Dd_PMC_SPI_Get_Ctrl( NULL );
			Ddim_Print(("Dd_PMC_SPI_Get_Ctrl(): spi_ctrl is NULL. ret=%X\n", ret ));
			break;
		case 3:
			ret = Dd_PMC_SPI_Set_Send_Data( NULL, 1 );
			Ddim_Print(("Dd_PMC_SPI_Set_Send_Data(): send_addr is NULL. ret=%X\n", ret ));
			break;
		case 4:
			ret = Dd_PMC_SPI_Set_Send_Data( (VOID*)gCT_DD_PMC_SPI_Send_Data_Addr, 0 );
			Ddim_Print(("Dd_PMC_SPI_Set_Send_Data(): data num is 0. ret=%X\n", ret ));
			break;
		case 5:
			ret = Dd_PMC_SPI_Set_Recv_Data( NULL, 1 );
			Ddim_Print(("Dd_PMC_SPI_Set_Recv_Data(): recv_addr is NULL. ret=%X\n", ret ));
			break;
		case 6:
			ret = Dd_PMC_SPI_Set_Recv_Data( (VOID*)gCT_DD_PMC_SPI_Recv_Data_Addr, 0 );
			Ddim_Print(("Dd_PMC_SPI_Set_Recv_Data(): data num is 0. ret=%X\n", ret ));
			break;
		case 7:
			ret = Dd_PMC_SPI_Set_Slave_Select( NULL );
			Ddim_Print(("Dd_PMC_SPI_Set_Slave_Select(): ss_info is NULL. ret=%X\n", ret ));
			break;
		case 8:
			ret = Dd_PMC_SPI_Get_Slave_Select( NULL );
			Ddim_Print(("Dd_PMC_SPI_Get_Slave_Select(): ss_info is NULL. ret=%X\n", ret ));
			break;
		case 9:
			ret = Dd_PMC_SPI_Get_Clock_Divisor( NULL );
			Ddim_Print(("Dd_PMC_SPI_Get_Clock_Divisor(): clk_div is NULL. ret=%X\n", ret ));
			break;
		case 10:
			ret = Dd_PMC_SPI_Calculate( 1, NULL );
			Ddim_Print(("Dd_PMC_SPI_Calculate(): clk_div is NULL. ret=%X\n", ret ));
			break;
		default:
			Ddim_Print(("please check 2nd parameter!!\n"));
			break;
		}
	}
	else{
		Ddim_Print(("please check 1st parameter!!\n"));
	}
	return ;
}
